use actix_web::web::{Data, Json, Query};

use crate::{
    common::{
        app::tags::USER,
        types::{ApiPageResult, ApiResult},
    },
    config::{auth::AuthInfo, state::AppState},
    models::{
        request::{
            common_request::IdRequest,
            user_req::{
                ChangePasswordRequest, CreateUserRequest, ModifyUser, PageUserRequest,
                UpdateUserRequest,
            },
        },
        response::user_res::{UserCreated, UserDetail, UserInfo, UserPage},
    },
    services::user_service as UserService,
};

/// 创建用户
#[utoipa::path(
    tags = [USER],
    get,
    path = "/api/v1/user/create",
    responses(
        (status = 200, description = "Ok", body = UserCreated),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = CreateUserRequest
)]
pub async fn create(
    state: Data<AppState>,
    req: Json<CreateUserRequest>,
    auth_info: AuthInfo,
) -> ApiResult<UserCreated> {
    UserService::create(state, req.into_inner(), auth_info).await
}

/// 更新用户
#[utoipa::path(
    tags = [USER],
    post,
    path = "/api/v1/user/update",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = UpdateUserRequest
)]
pub async fn update(
    state: Data<AppState>,
    req: Json<UpdateUserRequest>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    UserService::update(state, req.into_inner(), auth_info).await
}

/// 修改用户
#[utoipa::path(
    tags = [USER],
    post,
    path = "/api/v1/user/modify",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = ModifyUser
)]
pub async fn modify(
    state: Data<AppState>,
    req: Json<ModifyUser>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    UserService::modify(state, req.into_inner(), auth_info).await
}

/// 删除用户
#[utoipa::path(
    tags = [USER],
    post,
    path = "/api/v1/user/delete",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn delete(
    state: Data<AppState>,
    req: Json<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    UserService::delete(state, req.into_inner(), auth_info).await
}

/// 用户信息
#[utoipa::path(
    tags = [USER],
    get,
    path = "/api/v1/user/info",
    responses(
        (status = 200, description = "Ok", body = UserInfo),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    )
)]
pub async fn info(state: Data<AppState>, auth_info: AuthInfo) -> ApiResult<UserInfo> {
    UserService::info(state, auth_info).await
}

/// 用户分页
#[utoipa::path(
    tags = [USER],
    get,
    path = "/api/v1/user/page",
    responses(
        (status = 200, description = "Ok", body = UserPage),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = PageUserRequest
)]
pub async fn page(
    state: Data<AppState>,
    req: Query<PageUserRequest>,
    auth_info: AuthInfo,
) -> ApiPageResult<UserPage> {
    UserService::page(state, req.into_inner(), auth_info).await
}

/// 用户详情
#[utoipa::path(
    tags = [USER],
    get,
    path = "/api/v1/user/detail",
    responses(
        (status = 200, description = "Ok", body = UserDetail),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn detail(
    state: Data<AppState>,
    req: Query<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<UserDetail> {
    UserService::detail(state, req.into_inner(), auth_info).await
}

/// 修改密码
#[utoipa::path(
    tags = [USER],
    post,
    path = "/api/v1/user/change_password",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = ChangePasswordRequest
)]
pub async fn change_password(
    state: Data<AppState>,
    req: Json<ChangePasswordRequest>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    UserService::change_password(state, req.into_inner(), auth_info).await
}

/// 重置密码
#[utoipa::path(
    tags = [USER],
    post,
    path = "/api/v1/user/reset_password",
    responses(
        (status = 200, description = "Ok", body = UserCreated),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn reset_password(
    state: Data<AppState>,
    req: Json<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<UserCreated> {
    UserService::reset_password(state, req.into_inner(), auth_info).await
}
